﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ArduinoInterOp
{
    public class ArduinoPinValuesData
    {
        private readonly ArduinoPinsManager _manager;
        private readonly Dictionary<byte, ArduinoPinValueData> _pinValueIndexedByPinNumber;

        internal ArduinoPinValuesData(ArduinoPinsManager manager)
        {
            _manager = manager;
            _pinValueIndexedByPinNumber = new Dictionary<byte, ArduinoPinValueData>();
        }

        internal void UpdatePin(byte pinNumber, ushort value, long operationTicks)
        {
            if (!this._pinValueIndexedByPinNumber.ContainsKey(pinNumber))
            {
                // TODO
                throw new Exception();
            }

            var pinData = this._pinValueIndexedByPinNumber[pinNumber];

            if (pinData.LastModifiedInTicks < operationTicks)
            {
                pinData.LastModifiedInTicks = operationTicks;

                var oldValue = pinData.Value;
                pinData.Value = value;

                if (pinData.ChangeDelta != 0 && Math.Abs(value - oldValue) >= pinData.ChangeDelta)
                {
                    pinData.OnValueChanged(e: new PinValueChangedEventArgs
                                                  {
                                                      LastValue = oldValue
                                                  });
                }
            }
        }

        public ArduinoPinValueData this[byte pinNumber]
        {
            get
            {
                if (_pinValueIndexedByPinNumber.ContainsKey(pinNumber))
                {
                    return this._pinValueIndexedByPinNumber[pinNumber];
                }
                return null;
            }
        }

        public void Add(byte pinNumber)
        {
            if(!_pinValueIndexedByPinNumber.ContainsKey(pinNumber))
            {
                _pinValueIndexedByPinNumber.Add(pinNumber, new ArduinoPinValueData(pinNumber, _manager));
            }
            else
            {
                // TODO:
                throw new Exception();
            }
        }
    }
}
